home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 December / enter-cd-12-2005.iso / Internet / SpamAware 4.0 / SpamAware-Setup.exe / {app} / rules / 20_html_tests.cf < prev    next >
Encoding:
Text File  |  2005-06-20  |  15.4 KB  |  309 lines

  1. # SpamAssassin rules file: HTML tests
  2. #
  3. # Please don't modify this file as your changes will be overwritten with
  4. # the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead.
  5. # See 'perldoc Mail::SpamAssassin::Conf' for details.
  6. #
  7. # <@LICENSE>
  8. # Copyright 2004 Apache Software Foundation
  9. # Licensed under the Apache License, Version 2.0 (the "License");
  10. # you may not use this file except in compliance with the License.
  11. # You may obtain a copy of the License at
  12. #     http://www.apache.org/licenses/LICENSE-2.0
  13. # Unless required by applicable law or agreed to in writing, software
  14. # distributed under the License is distributed on an "AS IS" BASIS,
  15. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. # See the License for the specific language governing permissions and
  17. # limitations under the License.
  18. # </@LICENSE>
  19. #
  20. ###########################################################################
  21.  
  22. require_version @@VERSION@@
  23.  
  24. # HTML parser tests
  25. #
  26. # please sort these by eval type then name
  27.  
  28. # HTML control test, HTML spam rules should all have better S/O than this
  29. body HTML_MESSAGE        eval:html_test('html_message')
  30. describe HTML_MESSAGE        HTML included in message
  31.  
  32. # the HTML percentage range
  33. # should really be converted into a numeric function test
  34. body HTML_00_10            eval:html_range('ratio','0.00','0.10')
  35. body HTML_10_20            eval:html_range('ratio','0.10','0.20')
  36. body HTML_20_30            eval:html_range('ratio','0.20','0.30')
  37. body HTML_30_40            eval:html_range('ratio','0.30','0.40')
  38. body HTML_40_50            eval:html_range('ratio','0.40','0.50')
  39. body HTML_50_60            eval:html_range('ratio','0.50','0.60')
  40. body HTML_60_70            eval:html_range('ratio','0.60','0.70')
  41. body HTML_70_80            eval:html_range('ratio','0.70','0.80')
  42. body HTML_80_90            eval:html_range('ratio','0.80','0.90')
  43. body HTML_90_100        eval:html_range('ratio','0.90','1.00')
  44. describe HTML_00_10        Message is 0% to 10% HTML
  45. describe HTML_10_20        Message is 10% to 20% HTML
  46. describe HTML_20_30        Message is 20% to 30% HTML
  47. describe HTML_30_40        Message is 30% to 40% HTML
  48. describe HTML_40_50        Message is 40% to 50% HTML
  49. describe HTML_50_60        Message is 50% to 60% HTML
  50. describe HTML_60_70        Message is 60% to 70% HTML
  51. describe HTML_70_80        Message is 70% to 80% HTML
  52. describe HTML_80_90        Message is 80% to 90% HTML
  53. describe HTML_90_100        Message is 90% to 100% HTML
  54.  
  55. # HTML shouting range
  56. # should really be converted into a numeric function test
  57. body HTML_SHOUTING3        eval:html_range('max_shouting','2','3')
  58. body HTML_SHOUTING4        eval:html_range('max_shouting','3','4')
  59. body HTML_SHOUTING5        eval:html_range('max_shouting','4','5')
  60. body HTML_SHOUTING6        eval:html_range('max_shouting','5','6')
  61. body HTML_SHOUTING7        eval:html_range('max_shouting','6','7')
  62. describe HTML_SHOUTING3        HTML has very strong "shouting" markup
  63. describe HTML_SHOUTING4        HTML has very strong "shouting" markup
  64. describe HTML_SHOUTING5        HTML has very strong "shouting" markup
  65. describe HTML_SHOUTING6        HTML has very strong "shouting" markup
  66. describe HTML_SHOUTING7        HTML has very strong "shouting" markup
  67.  
  68. body HTML_TEXT_AFTER_HTML    eval:html_test('text_after_html')
  69. describe HTML_TEXT_AFTER_HTML    HTML contains text after HTML close tag
  70.  
  71. body HTML_TEXT_AFTER_BODY    eval:html_test('text_after_body')
  72. describe HTML_TEXT_AFTER_BODY    HTML contains text after BODY close tag
  73.  
  74. # HTML comment tests
  75. body HTML_COMMENT_SHORT        eval:html_text_match('comment', '<!(?!-).{0,6}>')
  76. describe HTML_COMMENT_SHORT    HTML comment is very short
  77.  
  78. body HTML_COMMENT_SAVED_URL    eval:html_text_match('comment', '<!-- saved from url=\(\d{4}\)')
  79. describe HTML_COMMENT_SAVED_URL    HTML message is a saved web page
  80.  
  81. # Comment is a spam sign when following <DIV>
  82. body HTML_CONVERTED        eval:html_test('div_converted')
  83. describe HTML_CONVERTED        HTML conversion tool used by spam
  84.  
  85. body HTML_EMBEDS        eval:html_test('embeds')
  86. describe HTML_EMBEDS        HTML with embedded plugin object
  87.  
  88. body HTML_EVENT_UNSAFE        eval:html_test('html_event_unsafe')
  89. describe HTML_EVENT_UNSAFE    HTML contains unsafe auto-executing code
  90.  
  91. body HTML_FONT_SIZE_TINY    eval:html_eval('min_size', '< 1')
  92. describe HTML_FONT_SIZE_TINY    HTML font size is tiny
  93.  
  94. body HTML_FONT_SIZE_NONE    eval:html_eval('min_size', '< 0')
  95. describe HTML_FONT_SIZE_NONE    HTML font size is negative
  96.  
  97. body HTML_FONT_SIZE_LARGE    eval:html_range('max_size', '5', '6')
  98. describe HTML_FONT_SIZE_LARGE    HTML font size is large
  99.  
  100. body HTML_FONT_SIZE_HUGE    eval:html_range('max_size', '6', 'inf')
  101. describe HTML_FONT_SIZE_HUGE    HTML font size is huge
  102.  
  103. body HTML_FONT_BIG        eval:html_test('big_font')
  104. describe HTML_FONT_BIG        HTML tag for a big font size
  105.  
  106. body HTML_FONT_TINY        eval:html_test('tiny_font')
  107. describe HTML_FONT_TINY        HTML tag for a tiny font size
  108.  
  109. body HTML_FONT_INVISIBLE    eval:html_test('font_invisible')
  110. describe HTML_FONT_INVISIBLE    HTML font color is same as background
  111.  
  112. body HTML_FONT_LOW_CONTRAST    eval:html_test('font_low_contrast')
  113. describe HTML_FONT_LOW_CONTRAST    HTML font color similar to background
  114.  
  115. body HTML_FONT_FACE_BAD        eval:html_test('font_face_bad')
  116. describe HTML_FONT_FACE_BAD    HTML font face is not a word
  117.  
  118. body HTML_FONT_FACE_CAPS    eval:html_test('font_face_caps')
  119. describe HTML_FONT_FACE_CAPS    HTML font face has excess capital characters
  120.  
  121. body HTML_FORMACTION_MAILTO    eval:html_test('form_action_mailto')
  122. describe HTML_FORMACTION_MAILTO    HTML includes a form which sends mail
  123.  
  124. # HTML_IMAGE_ONLY - not much raw HTML with images (absolute)
  125. body HTML_IMAGE_ONLY_04        eval:html_image_only('0000','0400')
  126. body HTML_IMAGE_ONLY_08        eval:html_image_only('0400','0800')
  127. body HTML_IMAGE_ONLY_12        eval:html_image_only('0800','1200')
  128. body HTML_IMAGE_ONLY_16        eval:html_image_only('1200','1600')
  129. body HTML_IMAGE_ONLY_20        eval:html_image_only('1600','2000')
  130. body HTML_IMAGE_ONLY_24        eval:html_image_only('2000','2400')
  131. describe HTML_IMAGE_ONLY_04    HTML: images with 0-400 bytes of words
  132. describe HTML_IMAGE_ONLY_08    HTML: images with 400-800 bytes of words
  133. describe HTML_IMAGE_ONLY_12    HTML: images with 800-1200 bytes of words
  134. describe HTML_IMAGE_ONLY_16    HTML: images with 1200-1600 bytes of words
  135. describe HTML_IMAGE_ONLY_20    HTML: images with 1600-2000 bytes of words
  136. describe HTML_IMAGE_ONLY_24    HTML: images with 2000-2400 bytes of words
  137.  
  138. # HTML_IMAGE_RATIO - more image area than text (ratio)
  139. body HTML_IMAGE_RATIO_02    eval:html_image_ratio('0.000','0.002')
  140. body HTML_IMAGE_RATIO_04    eval:html_image_ratio('0.002','0.004')
  141. body HTML_IMAGE_RATIO_06    eval:html_image_ratio('0.004','0.006')
  142. body HTML_IMAGE_RATIO_08    eval:html_image_ratio('0.006','0.008')
  143. describe HTML_IMAGE_RATIO_02    HTML has a low ratio of text to image area
  144. describe HTML_IMAGE_RATIO_04    HTML has a low ratio of text to image area
  145. describe HTML_IMAGE_RATIO_06    HTML has a low ratio of text to image area
  146. describe HTML_IMAGE_RATIO_08    HTML has a low ratio of text to image area
  147.  
  148. body HTML_LINK_PUSH_HERE    eval:html_text_match('anchor', '(?i)(?:push|go)\s*(?:here|this)')
  149. describe HTML_LINK_PUSH_HERE    HTML link text says "push here" or similar
  150.  
  151. # HTML obfuscation
  152. body HTML_OBFUSCATE_05_10    eval:html_range('obfuscation_ratio','.05','.1')
  153. body HTML_OBFUSCATE_10_20    eval:html_range('obfuscation_ratio','.1','.2')
  154. body HTML_OBFUSCATE_20_30    eval:html_range('obfuscation_ratio','.2','.3')
  155. body HTML_OBFUSCATE_30_40    eval:html_range('obfuscation_ratio','.3','.4')
  156. body HTML_OBFUSCATE_40_50    eval:html_range('obfuscation_ratio','.4','.5')
  157. body HTML_OBFUSCATE_50_60    eval:html_range('obfuscation_ratio','.5','.6')
  158. body HTML_OBFUSCATE_60_70    eval:html_range('obfuscation_ratio','.6','.7')
  159. body HTML_OBFUSCATE_70_80    eval:html_range('obfuscation_ratio','.7','.8')
  160. body HTML_OBFUSCATE_80_90    eval:html_range('obfuscation_ratio','.8','.9')
  161. body HTML_OBFUSCATE_90_100    eval:html_range('obfuscation_ratio','.9','1.0')
  162. describe HTML_OBFUSCATE_05_10    Message is 5% to 10% HTML obfuscation
  163. describe HTML_OBFUSCATE_10_20    Message is 10% to 20% HTML obfuscation
  164. describe HTML_OBFUSCATE_20_30    Message is 20% to 30% HTML obfuscation
  165. describe HTML_OBFUSCATE_30_40    Message is 30% to 40% HTML obfuscation
  166. describe HTML_OBFUSCATE_40_50    Message is 40% to 50% HTML obfuscation
  167. describe HTML_OBFUSCATE_50_60    Message is 50% to 60% HTML obfuscation
  168. describe HTML_OBFUSCATE_60_70    Message is 60% to 70% HTML obfuscation
  169. describe HTML_OBFUSCATE_70_80    Message is 70% to 80% HTML obfuscation
  170. describe HTML_OBFUSCATE_80_90    Message is 80% to 90% HTML obfuscation
  171. describe HTML_OBFUSCATE_90_100    Message is 90% to 100% HTML obfuscation
  172.  
  173. # backhair - idea from backhair set by Jennifer Wheeler and Adam Lopresto.
  174. body HTML_BACKHAIR_2        eval:html_range('backhair_count', '1', '4')
  175. body HTML_BACKHAIR_4        eval:html_range('backhair_count', '4', '8')
  176. body HTML_BACKHAIR_8        eval:html_range('backhair_count', '8', 'inf')
  177. describe HTML_BACKHAIR_2    HTML tags used to obfuscate words
  178. describe HTML_BACKHAIR_4    HTML tags used to obfuscate words
  179. describe HTML_BACKHAIR_8    HTML tags used to obfuscate words
  180.  
  181. # HTML attribute testing
  182. body HTML_ATTR_BAD        eval:html_range('attr_bad','0.75','1.0')
  183. describe HTML_ATTR_BAD        HTML has many bad attributes in tags
  184. body HTML_ATTR_UNIQUE        eval:html_range('attr_unique_bad','0.5','1.0')
  185. describe HTML_ATTR_UNIQUE    HTML appears to have random attributes in tags
  186.  
  187. body HTML_WEB_BUGS        eval:html_test('web_bugs')
  188. describe HTML_WEB_BUGS        Image tag intended to identify you
  189.  
  190. body HTML_TAG_BALANCE_BODY    eval:html_tag_balance('body', '!= 0')
  191. describe HTML_TAG_BALANCE_BODY    HTML has unbalanced "body" tags
  192.  
  193. body HTML_TAG_BALANCE_HEAD    eval:html_tag_balance('head', '!= 0')
  194. describe HTML_TAG_BALANCE_HEAD    HTML has unbalanced "head" tags
  195.  
  196. body HTML_TAG_EXIST_MARQUEE    eval:html_tag_exists('marquee')
  197. describe HTML_TAG_EXIST_MARQUEE    HTML has "marquee" tag
  198.  
  199. body HTML_TAG_EXIST_TBODY    eval:html_tag_exists('tbody')
  200. describe HTML_TAG_EXIST_TBODY    HTML has "tbody" tag
  201.  
  202. # percentage of tags that are not legal elements in HTML
  203. body HTML_BADTAG_00_10    eval:html_range('bad_tag_ratio','0.00','0.10')
  204. body HTML_BADTAG_10_20    eval:html_range('bad_tag_ratio','0.10','0.20')
  205. body HTML_BADTAG_20_30    eval:html_range('bad_tag_ratio','0.20','0.30')
  206. body HTML_BADTAG_30_40    eval:html_range('bad_tag_ratio','0.30','0.40')
  207. body HTML_BADTAG_40_50    eval:html_range('bad_tag_ratio','0.40','0.50')
  208. body HTML_BADTAG_50_60    eval:html_range('bad_tag_ratio','0.50','0.60')
  209. body HTML_BADTAG_60_70    eval:html_range('bad_tag_ratio','0.60','0.70')
  210. body HTML_BADTAG_70_80    eval:html_range('bad_tag_ratio','0.70','0.80')
  211. body HTML_BADTAG_80_90    eval:html_range('bad_tag_ratio','0.80','0.90')
  212. body HTML_BADTAG_90_100    eval:html_range('bad_tag_ratio','0.90','1.00')
  213. describe HTML_BADTAG_00_10    HTML message is 0% to 10% bad tags
  214. describe HTML_BADTAG_10_20    HTML message is 10% to 20% bad tags
  215. describe HTML_BADTAG_20_30    HTML message is 20% to 30% bad tags
  216. describe HTML_BADTAG_30_40    HTML message is 30% to 40% bad tags
  217. describe HTML_BADTAG_40_50    HTML message is 40% to 50% bad tags
  218. describe HTML_BADTAG_50_60    HTML message is 50% to 60% bad tags
  219. describe HTML_BADTAG_60_70    HTML message is 60% to 70% bad tags
  220. describe HTML_BADTAG_70_80    HTML message is 70% to 80% bad tags
  221. describe HTML_BADTAG_80_90    HTML message is 80% to 90% bad tags
  222. describe HTML_BADTAG_90_100    HTML message is 90% to 100% bad tags
  223.  
  224. # percentage of unique non-elements in HTML
  225. body HTML_NONELEMENT_00_10    eval:html_range('non_element_ratio','0.00','0.10')
  226. body HTML_NONELEMENT_10_20    eval:html_range('non_element_ratio','0.10','0.20')
  227. body HTML_NONELEMENT_20_30    eval:html_range('non_element_ratio','0.20','0.30')
  228. body HTML_NONELEMENT_30_40    eval:html_range('non_element_ratio','0.30','0.40')
  229. body HTML_NONELEMENT_40_50    eval:html_range('non_element_ratio','0.40','0.50')
  230. body HTML_NONELEMENT_50_60    eval:html_range('non_element_ratio','0.50','0.60')
  231. body HTML_NONELEMENT_60_70    eval:html_range('non_element_ratio','0.60','0.70')
  232. body HTML_NONELEMENT_70_80    eval:html_range('non_element_ratio','0.70','0.80')
  233. body HTML_NONELEMENT_80_90    eval:html_range('non_element_ratio','0.80','0.90')
  234. body HTML_NONELEMENT_90_100    eval:html_range('non_element_ratio','0.90','1.00')
  235. describe HTML_NONELEMENT_00_10    0% to 10% of HTML elements are non-standard
  236. describe HTML_NONELEMENT_10_20    10% to 20% of HTML elements are non-standard
  237. describe HTML_NONELEMENT_20_30    20% to 30% of HTML elements are non-standard
  238. describe HTML_NONELEMENT_30_40    30% to 40% of HTML elements are non-standard
  239. describe HTML_NONELEMENT_40_50    40% to 50% of HTML elements are non-standard
  240. describe HTML_NONELEMENT_50_60    50% to 60% of HTML elements are non-standard
  241. describe HTML_NONELEMENT_60_70    60% to 70% of HTML elements are non-standard
  242. describe HTML_NONELEMENT_70_80    70% to 80% of HTML elements are non-standard
  243. describe HTML_NONELEMENT_80_90    80% to 90% of HTML elements are non-standard
  244. describe HTML_NONELEMENT_90_100    90% to 100% of HTML elements are non-standard
  245.  
  246. # short HTML messages with certain attributes
  247. body HTML_SHORT_LENGTH        eval:html_eval('length', '< 170')
  248. describe HTML_SHORT_LENGTH    HTML is extremely short
  249.  
  250. body __HTML_LENGTH_512        eval:html_eval('length', '< 512')
  251. body __COMMENT_EXISTS        eval:html_text_match('comment', '<!.*?>')
  252. meta HTML_SHORT_COMMENT        (__HTML_LENGTH_512 && __COMMENT_EXISTS)
  253. describe HTML_SHORT_COMMENT    HTML is very short with HTML comments
  254.  
  255. body __HTML_LENGTH_384        eval:html_eval('length', '< 384')
  256. body __TAG_EXISTS_CENTER    eval:html_tag_exists('center')
  257. meta HTML_SHORT_CENTER        (__HTML_LENGTH_384 && __TAG_EXISTS_CENTER)
  258. describe HTML_SHORT_CENTER    HTML is very short with CENTER tag
  259.  
  260. body HTML_TITLE_EMPTY        eval:html_text_not_match('title', '(?s)\S')
  261. describe HTML_TITLE_EMPTY    HTML title contains no text
  262.  
  263. body HTML_TITLE_UNTITLED    eval:html_text_match('title', '(?i)(?:untitled|new page \d+)')
  264. describe HTML_TITLE_UNTITLED    HTML title contains "Untitled"
  265.  
  266. ###########################################################################
  267. # meta tests
  268.  
  269. body __HTML_CHARSET_FARAWAY    eval:html_charset_faraway()
  270. meta HTML_CHARSET_FARAWAY    (__HTML_CHARSET_FARAWAY && __HIGHBITS)
  271. describe HTML_CHARSET_FARAWAY    A foreign language charset used in HTML markup
  272. tflags HTML_CHARSET_FARAWAY    userconf
  273.  
  274. meta HTML_MIME_NO_HTML_TAG    MIME_HTML_ONLY && !__TAG_EXISTS_HTML
  275. describe HTML_MIME_NO_HTML_TAG    HTML-only message, but there is no HTML tag
  276.  
  277. meta HTML_MISSING_CTYPE        (!__MIME_HTML && HTML_MESSAGE)
  278. describe HTML_MISSING_CTYPE    Message is HTML without HTML Content-Type
  279.  
  280. ###########################################################################
  281. # rawbody HTML tests
  282.  
  283. rawbody HIDE_WIN_STATUS        /<[^>]+onMouseOver=[^>]+window\.status=/i
  284. describe HIDE_WIN_STATUS    Javascript to hide URLs in browser
  285.  
  286. rawbody __OBFUSCATING_COMMENT_A    /\w(?:<![^>]*>)+\w/
  287. rawbody __OBFUSCATING_COMMENT_B    /[^\s>](?:<![^>]*>)+[^\s<]/
  288. meta OBFUSCATING_COMMENT    ((__OBFUSCATING_COMMENT_A && HTML_MESSAGE) || (__OBFUSCATING_COMMENT_B && MIME_HTML_ONLY))
  289. describe OBFUSCATING_COMMENT    HTML comments which obfuscate text
  290.  
  291. # spams that are assembled from a Javascript array
  292. # look for the XOR op
  293. rawbody __JS_FROMCHARCODE       /String\.fromCharCode\s*\(\s*\S+\s*\[\s*\S+\s*\]\s*\^/
  294. rawbody __JS_DOCWRITE           /document\.write/
  295. meta JS_FROMCHARCODE            (__JS_FROMCHARCODE && __JS_DOCWRITE)
  296. describe JS_FROMCHARCODE        Document is built from a Javascript charcode array
  297.  
  298. # A-Z, a-z, 0-9
  299. rawbody ENTITY_DEC_ALPHANUM    /\&\#0*(?:4[89]|5[0-7]|6[5-9][78]\d|9[0789]|1[01]\d|12[012])\;/
  300. describe ENTITY_DEC_ALPHANUM    HTML contains needlessly encoded characters
  301.  
  302. # ! $ % ' ( ) , - . / : ; = ? @ _
  303. # a good possible rule that may resurface
  304. #rawbody ENTITY_DEC_OTHER    /\&\#0*(?:3[3679]|4[014567]|5[89]|6[134]|95)\;/
  305. #describe ENTITY_DEC_OTHER    HTML contains needlessly encoded punctuation
  306.